<script setup lang="ts">
/**
 * @description 一个通用的“审核管理”页面，使用这个页面的角色有“业务员”和“地区经理”。
 * 对于“业务员”，这个页面用于查看已提交的项目的审核情况。
 * 对于“地区经理”，这个页面用于查看由业务员提交的需要审批的以及审批通过或驳回的项目。
 */

import dayjs from 'dayjs'
import { useLoadMore } from 'vue-request'
import { useProjectConfigStore } from '@/store/projectConfig'
import { useUserInfoStore } from '@/store/userInfo'
import { fetchProjectVerifyListAPI } from '@/apis/fetchProjectVerifyList'
import { verifyProjectAPI } from '@/apis/verifyProject'
import type { InfoGridItem } from '@/components/ProjectTable.vue'

// Assets
import modalRejectIcon from '@/static/images/modal/reject.png'
import { useSearch } from '@/composables/search'

const router = useRouter()
const userInfoStore = useUserInfoStore()
const projectConfigStore = useProjectConfigStore()

/* ------------------------------- Tabs START ------------------------------- */
const tabConfiguration = [{ name: '全部' }, { name: '待审核' }, { name: '审核通过' }, { name: '审核驳回' }]
const selectedTabName = ref<'全部' | '待审核' | '审核通过' | '审核驳回'>('全部')
/* -------------------------------- Tabs END -------------------------------- */

/* ------------------------------- 列表数据 START ------------------------------- */
// 项目数据
const { dataList, loading, loadingMore, noMore, loadMore, refresh } = useLoadMore<LoadMoreData<Project>>(
  fetchProjects,
  { isNoMore: d => d?.list.length === d?.total },
)
// 搜索
const { searchText, isOpenSearch, searching, searchResult, fetchSearchResult } = useSearch<Project>(search)

const finalList = computed(() => {
  if (isOpenSearch.value)
    return searchResult.value
  else
    return dataList.value
})

// “加载更多”的状态
const loadMoreStatus = computed(() => {
  if (loadingMore.value)
    return 'loading'
  else if (noMore.value)
    return 'nomore'
  else
    return 'loadmore'
})

/**
 * @description useLoadMore 所必需的服务函数
 *
 * @param d - useLoadMore 中的 `data`
 */
async function fetchProjects(d?: LoadMoreData<Project>): Promise<LoadMoreData<Project>> {
  // 当前页数
  const _page = d?.page ? d.page + 1 : 1
  // 当前状态
  const projectVerifyStatusCode = projectConfigStore.projectVerifyStatusCode[selectedTabName.value]
  // 发起请求
  const res = await fetchProjectVerifyListAPI({
    page: _page.toString(),
    limit: '10',
    status: projectVerifyStatusCode,
    keyword: searchText.value.length > 0 ? searchText.value : undefined,
  }, userInfoStore.userInfo!.token!)

  return {
    list: res.data?.data.data || [],
    page: _page,
    total: res.data?.data.total || 9999,
  }
}

async function search() {
  const projectVerifyStatusCode = projectConfigStore.projectVerifyStatusCode[selectedTabName.value]
  const res = await fetchProjectVerifyListAPI({
    page: '1',
    limit: '100',
    status: projectVerifyStatusCode,
    keyword: searchText.value.length > 0 ? searchText.value : undefined,
  }, userInfoStore.userInfo!.token!)
  return res.data!
}

onReady(() => {
  if (userInfoStore.belongTo(['4']))
    uni.setNavigationBarTitle({ title: '审核管理' })
  else if (userInfoStore.belongTo(['1']))
    uni.setNavigationBarTitle({ title: '审批管理' })
})
onShow(() => refresh())
onReachBottom(() => loadMore())
/* -------------------------------- 列表数据 END -------------------------------- */

/* ----------------------------- 计算用于显示的信息 START ---------------------------- */
const searchPlaceholder = computed(() => {
  if (userInfoStore.belongTo(['4']))
    return '请输入业主姓名/手机号'
  else if (userInfoStore.belongTo(['1']))
    return '请输入业主、业务员的姓名、手机号'
})

function getStatusTagColor(status: string) {
  if (status === '1')
    return '#FF6D0A'
  else if (status === '2')
    return '#0FCB71'
  else if (status === '3')
    return '#FF2636'
}

function getTableInfo(project: Project): InfoGridItem[] {
  if (userInfoStore.belongTo(['4'])) {
    return [
      { label: '业务员', value: project.salesman_name || '未知' },
      { label: '项目总额', value: `¥${project.money_total}`, color: '#FF2636' },
      { label: '装修类型', value: project.project_type_name || '未知' },
      { label: '工期截止', value: project.duration ? dayjs.unix(Number(project.duration)).format('YYYY.MM.DD') : '未知' },
      { label: '装修面积', value: `${project.extent}` },
      { label: '当前节点', value: project.node_name || '未开始', color: '#FF6D0A' },
    ]
  }
  else if (userInfoStore.belongTo(['1'])) {
    return [
      { label: '业务员', value: project.salesman_name || '未知' },
      { label: '项目总额', value: `¥${project.money_total}`, color: '#FF2636' },
      { label: '装修类型', value: project.project_type_name || '未知' },
      { label: '工期截止', value: project.duration ? dayjs.unix(Number(project.duration)).format('YYYY.MM.DD') : '未知' },
      { label: '装修面积', value: `${project.extent}` },
      { label: '业主', value: project.contacts_name || '未知', showTag: true },
    ]
  }
  else {
    return []
  }
}
/* ------------------------------ 计算用于显示的信息 END ----------------------------- */

/* ------------------------------- 通用事件处理 START ------------------------------- */
const handleSearch = useDebounceFn((keyword: string) => {
  searchText.value = keyword
  fetchSearchResult()
}, 500)

function handleTabChange(e: any) {
  selectedTabName.value = e.name
  uni.pageScrollTo({ scrollTop: 0, duration: 0 })
  refresh()
}

function handleTapProject(project: Project) {
  router.push({
    name: 'verifyDetail',
    params: { project_id: project.id!.toString()! },
  })
}
/* -------------------------------- 通用事件处理 END -------------------------------- */

/* ------------------------------ 经理 Part START ----------------------------- */
const isShowRejectModal = ref(false)
// 对某个项目执行通过或驳回操作时，将 id 暂存到这里
const tempProjectId = ref('')
// 拒绝理由
const reason = ref('')

function handleReject(projectId: string) {
  tempProjectId.value = projectId
  isShowRejectModal.value = true
}

async function handleConfirmReject() {
  try {
    const res = await verifyProjectAPI({
      project_id: tempProjectId.value,
      verify: '3',
      verify_desc: reason.value,
    }, userInfoStore.userInfo!.token!)
    if (res.data?.code === 1) {
      refresh()
      uni.showToast({ title: '驳回完成', icon: 'none' })
    }
    else { uni.showToast({ title: res.data?.msg, icon: 'none' }) }
  }
  catch (error) {
    uni.showToast({ title: '驳回失败', icon: 'none' })
  }
  isShowRejectModal.value = false
  tempProjectId.value = ''
  reason.value = ''
}

function handleCancelReject() {
  isShowRejectModal.value = false
  tempProjectId.value = ''
  reason.value = ''
}

function handleAgree(projectId: string) {
  router.push({
    name: 'assignForeman',
    params: {
      project_id: projectId,
      is_initial: 'true',
    },
  })
}
/* ------------------------------- 经理 Part END ------------------------------ */
</script>

<template>
  <view class="min-h-screen bg-#F8F8F8">
    <view class="z-10 sticky top-0 left-0 w-750rpx bg-white">
      <Spacer height="30" />
      <view class="mx-30rpx border-1px border-solid border-#E3E3E3 rounded-6rpx">
        <uv-search
          shape="square" bg-color="#F8F9FD" color="#000000" search-icon-size="36rpx"
          search-icon-color="#FF6D0A" placeholder-color="#999999" :show-action="false"
          height="74rpx" :placeholder="searchPlaceholder"
          @change="handleSearch" @focus="isOpenSearch = true" @blur="isOpenSearch = false"
        />
      </view>
      <Spacer height="10" />
      <uv-tabs
        :list="tabConfiguration" line-color="#FF6D0A" line-width="48rpx" :active-style="{ color: '#000000', fontSize: '32rpx', lineHeight: '32rpx' }"
        :inactive-style="{ color: '#999999', fontSize: '28rpx', lineHeight: '28rpx' }"
        :custom-style="{ margin: '0 10rpx' }"
        @change="handleTabChange"
      />
    </view>

    <!-- 骨架屏 -->
    <view v-if="(loading && !loadingMore) || searching" class="p-30rpx bg-#F8F8F8">
      <!-- 骨架屏 Item -->
      <view v-for="i in 6" :key="i" class="flex flex-col mb-30rpx bg-white rounded-20rpx">
        <view class="relative flex flex-col pt-20rpx pr-157rpx pb-20rpx pl-30rpx">
          <view class="flex items-center h-48rpx">
            <view class="w-390rpx h-28rpx skeleton rounded-10rpx" />
          </view>
          <view v-show="userInfoStore.belongTo(['1'])" class="flex items-center mt-4rpx h-44rpx">
            <view v-show="userInfoStore.belongTo(['1'])" class="w-240rpx h-36rpx skeleton rounded-full" />
          </view>
          <view class="absolute top-0 right-0 w-120rpx h-44rpx skeleton rounded-tr-20rpx rounded-bl-12rpx" />
        </view>
        <Divider />
        <view class="p-30rpx">
          <ProjectTableSkeleton />
          <Spacer height="32rpx" />
        </view>
        <!-- 业务员 Part -->
        <block v-if="userInfoStore.belongTo(['4'])">
          <Divider />
          <view class="flex flex-row-reverse justify-between items-center p-30rpx">
            <view class="w-257rpx h-18rpx skeleton rounded-10rpx" />
            <view class="flex items-center">
              <view class="w-58rpx h-28rpx skeleton rounded-10rpx" />
              <view class="ml-6rpx w-90rpx h-28rpx skeleton rounded-full" />
            </view>
          </view>
        </block>
        <!-- 地区经理 Part -->
        <Spacer v-if="userInfoStore.belongTo(['1'])" height="5" />
      </view>
    </view>

    <block v-else>
      <!-- 真实列表数据 -->
      <uv-list v-if="finalList.length > 0" :custom-style="{ padding: '30rpx', backgroundColor: '#F8F8F8' }">
        <uv-list-item
          v-for="project in finalList" :key="project.id"
          :custom-style="{ borderRadius: '20rpx', marginBottom: '30rpx' }"
        >
          <view class="flex flex-col bg-white rounded-20rpx" @tap="() => handleTapProject(project)">
            <view class="relative flex flex-col pt-20rpx pr-157rpx pb-20rpx pl-30rpx">
              <view class="text-28rpx leading-48rpx text-secondary">
                {{ project.name ? project.name : '未知项目' }}
              </view>
              <view
                v-if="userInfoStore.belongTo(['1'])"
                class="self-start mt-4rpx px-16rpx py-8rpx text-28rpx leading-28rpx text-brand bg-#FFEEE2 rounded-full"
              >
                当前节点：{{ project.node_name || '未开始' }}
              </view>
              <view
                class="absolute top-0 right-0 px-20rpx py-9rpx text-white text-28rpx leading-28rpx bg-brand rounded-tr-20rpx rounded-bl-12rpx"
                :style="{ backgroundColor: getStatusTagColor(`${project.verify}`) }"
              >
                {{ projectConfigStore.projectVerifyStatusStr[project.verify?.toString()!] || '未知' }}
              </view>
            </view>
            <Divider />
            <view class="p-30rpx">
              <ProjectTable :info="getTableInfo(project)" />
            </view>
            <!-- 业务员 Part -->
            <block v-if="userInfoStore.belongTo(['4'])">
              <Divider />
              <view class="flex flex-row-reverse justify-between items-center p-30rpx">
                <view class="text-24rpx leading-24rpx text-tertiary">
                  {{ project.create_time ? dayjs.unix(project.create_time).format('YYYY-MM-DD HH:mm:ss')
                    : '未知' }}
                </view>
                <view class="flex items-center">
                  <view class="text-30rpx leading-30rpx text-secondary font-bold">
                    {{ project.contacts_name || '未知' }}
                  </view>
                  <view class="ml-5rpx px-22rpx py-5rpx text-24rpx leading-24rpx text-white bg-brand rounded-full">
                    业主
                  </view>
                </view>
              </view>
            </block>
            <!-- 地区经理 Part -->
            <block v-if="userInfoStore.belongTo(['1']) && project.verify?.toString() === '1'">
              <Divider />
              <view class="flex flex-row-reverse justify-between items-center p-30rpx">
                <view class="flex">
                  <RGButton size="medium" corner="small" type="secondary" @tap.stop="handleReject(project.id?.toString()!)">
                    审核驳回
                  </RGButton>
                  <Spacer width="18" />
                  <RGButton size="medium" corner="small" type="primary" @tap.stop="handleAgree(project.id?.toString()!)">
                    审核通过
                  </RGButton>
                </view>
              </view>
            </block>
            <Spacer v-else height="5" />
          </view>
        </uv-list-item>
        <!-- 加载更多 -->
        <uv-load-more v-if="!isOpenSearch && dataList.length > 3" :status="loadMoreStatus" @loadmore="loadMore" />
      </uv-list>
      <!-- 页面缺省页 -->
      <PageDefault v-else />
    </block>

    <!-- 审核拒绝的弹窗 -->
    <uv-overlay :show="isShowRejectModal" @tap="isShowRejectModal">
      <uv-transition mode="zoom-in" :show="isShowRejectModal">
        <view class="relative w-screen h-screen">
          <JZTModal :icon="modalRejectIcon">
            <view class="flex flex-col items-center">
              <Spacer height="146" />
              <view class="text-34rpx leading-34rpx font-bold text-primary">
                确认审核驳回吗？
              </view>
              <Spacer height="42" />
              <view class="w-606rpx">
                <view class="text-28rpx leading-28rpx text-secondary">
                  驳回原因
                </view>
                <Spacer height="30" />
                <textarea v-model="reason" class="box-border w-full p-30rpx text-28rpx leading-48rpx text-secondary bg-#F8F8F8 rounded-10rpx" :maxlength="-1" placeholder="请输入驳回原因" />
              </view>
              <Spacer height="52" />
              <view class="flex justify-between items-center w-590rpx h-100rpx">
                <view
                  class="flex justify-center items-center w-280rpx h-100rpx text-32rpx leading-32rpx text-#FF6D0A font-bold bg-white border-1px border-solid border-#FF6D0A rounded-full"
                  @tap.stop="handleCancelReject"
                >
                  取消
                </view>
                <view
                  class="flex justify-center items-center w-280rpx h-100rpx text-32rpx leading-32rpx text-white font-bold bg-brand rounded-full"
                  @tap.stop="handleConfirmReject"
                >
                  确定
                </view>
              </view>
              <Spacer height="60" />
            </view>
          </JZTModal>
        </view>
      </uv-transition>
    </uv-overlay>
  </view>
</template>

<route lang="yaml">
name: 'review'
style:
  navigationBarBackgroundColor: '#FFFFFF'
  onReachBottomDistance: 100
layout: 'custom'
</route>
